"""
-- coding: utf-8 --
@Time : 2023/8/29
@Author : 张书译
@Describe:日志存储
"""

import os
import logging
import re
from datetime import datetime
from logging.handlers import TimedRotatingFileHandler
import config


class MyTimedRotatingFileHandler(TimedRotatingFileHandler):
    """
    时间为切割点日志
    """

    def getFilesToDelete(self):
        """
        Determine the files to delete when rolling over.
        More specific than the earlier method, which just used glob.glob().
        """
        dirName, baseName = os.path.split(self.baseFilename)
        fileNames = os.listdir(dirName)
        result = []
        # prefix = baseName + "."
        # plen = len(prefix)
        for fileName in fileNames:
            # if fileName[:plen] == prefix:
            # suffix = fileName[:-4]
            if self.extMatch.match(fileName):
                result.append(os.path.join(dirName, fileName))
        if len(result) < self.backupCount:
            result = []
        else:
            result.sort()
            result = result[:len(result) - self.backupCount]
        return result


class MyLogger:
    def __init__(self, when='D', backupCount=30):
        self.interval, self.suffix, self.extMatch, self.logName = self.fix(when)
        self.when = when
        self.backupCount = backupCount

    @staticmethod
    def fix(when):
        """
        filename：日志文件的路径和名称。如果不设置此参数，将默认输出到控制台。
        when：日志切割的时间间隔。可以选择的值有：“S”（秒），“M”（分钟），“H”（小时），“D”（天），“W0”-“W6”（周一到周日），“midnight”（每天凌晨）。
        interval：切割时间间隔的数量。
        backupCount：保留的日志文件个数。
        """
        if when == 'S':
            interval = 1  # one second
            suffix = "%Y-%m-%d_%H-%M-%S"
            extMatch = r"^\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}(.log)?$"
            logName = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
        elif when == 'M':
            interval = 60  # one minute
            suffix = "%Y-%m-%d_%H-%M"
            extMatch = r"^\d{4}-\d{2}-\d{2}_\d{2}-\d{2}(.log)?$"
            logName = datetime.now().strftime("%Y-%m-%d_%H-%M")
        elif when == 'H':
            interval = 60 * 60  # one hour
            suffix = "%Y-%m-%d_%H"
            extMatch = r"^\d{4}-\d{2}-\d{2}_\d{2}(.log)?$"
            logName = datetime.now().strftime("%Y-%m-%d_%H")
        elif when == 'D' or when == 'MIDNIGHT!':
            interval = 60 * 60 * 24  # one day
            suffix = "%Y-%m-%d.log"
            extMatch = r"^\d{4}-\d{2}-\d{2}(.log)?$"
            logName = datetime.now().strftime("%Y-%m-%d")
        elif when.startswith('w'):
            interval = 60 * 60 * 24 * 7  # one week
            if len(when) != 2:
                raise ValueError(
                    "You must specify a day for weekly rollover from 0 to 6 (0 is Monday): %s" % when)
            if when[1] < '0' or when[1] > '6':
                raise ValueError("Invalid day specified for weekly rollover: %s" % when)
            logName = datetime.now().strftime("%Y-%m-%d")
            suffix = "%Y-%m-%d"
            extMatch = r"^\d{4}-\d{2}-\d{2}(\.\w+)?$"
        else:
            interval = 1
            suffix = "%Y-%m-%d_%H-%M-%S"
            extMatch = r"ld{4J-\d{2}-\d{2J_\d{2}-(d{2J-\d{2J(.log)?$"
            logName = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
        return interval, suffix, extMatch, logName

    def split_file_name(self, filename):
        """
        修改日志文件名称
        """
        file_path = filename.split(f'{self.logName}.log.')
        # return f"flask_{''.join(file_path)}"
        return ''.join(file_path)

    def setup_log(self):

        # 创建logger对象,log_name: 日志名字
        logger_obj = logging.getLogger(f'{self.logName}.log')
        # loge文件路径
        log_file_path = os.path.join(config.LOG_DIR, f'{self.logName}.log')

        # when="MIDNIGHT", interval=1,表示每天0点为更新点，每天生成一个文件
        logger_handler = MyTimedRotatingFileHandler(filename=log_file_path, when=self.when, interval=self.interval,
                                                    backupCount=self.backupCount, encoding='utf-8')
        logger_handler.suffix = self.suffix

        # 处理日志文件名称
        logger_handler.namer = self.split_file_name

        # 修改后缀suffix,生成.log文件
        # extMatch是编译好正则表达式，用于匹配日志文件名后缀
        # 需要注意的是suffix和extMatch一定要匹配的上，如果不匹配，过期日志不会被删除
        logger_handler.suffix = f"{logger_handler.suffix}.log"
        # when=S: r"^\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}(.log)$"
        # when=M: r"^\d{4}-\d{2}-\d{2}_\d{2}-\d{2}(.log)$"
        # when=H: r"^\d{4}-\d{2}-\d{2}_\d{2}(.log)$"
        # when=D or MIDNIGHT : r"^\d{4}-\d{2}-\d{2}(.log)$"
        # when=W: r"^\d{4}-\d{2}-\d{2}(.log)$"
        logger_handler.extMatch = re.compile(self.extMatch, re.ASCII)

        # 创建日志输出格式
        logger_formatter = logging.Formatter(
            "[%(asctime)s] [%(process)d] [%(levelname)s] - %(module)s.%(funcName)s (%(filename)s:%(lineno)d) - %(message)s")

        # 配置日志输出格式
        logger_handler.setFormatter(logger_formatter)

        """设置CMD日志"""
        sh = logging.StreamHandler()

        # 增加日志处理器
        logger_obj.addHandler(logger_handler)
        logger_obj.addHandler(sh)

        # 设置日志的记录等级,常见等级有: DEBUG<INFO<WARING<ERROR
        logger_obj.setLevel(logging.INFO)

        return logger_obj


logger = MyLogger().setup_log()
